<template>
  <div class="chart-container">
    <!-- 工具栏：选择器 + 排序按钮 -->
    <div class="toolbar">
      <span class="label">电影类型：</span>

      <el-select
          v-model="selectedOption"
          placeholder="请选择电影类型"
          class="selector"
          style="width: 13vw; margin-left: 1vh; margin-right: 5vh"
      >
        <el-option
            v-for="item in genreOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
        />
      </el-select>

      <span class="sort-label">排序：</span>

      <span class="sort-group">
        <button
            :class="{ active: sortKey === 'hot' }"
            @click="setSort('hot')"
        >
          热度 <span>{{ sortOrder.hot === 'asc' ? '↑' : '↓' }}</span>
        </button>
        <button
            :class="{ active: sortKey === 'box' }"
            @click="setSort('box')"
        >
          票房 <span>{{ sortOrder.box === 'asc' ? '↑' : '↓' }}</span>
        </button>
      </span>
    </div>

    <!-- 图表 -->
    <v-chart ref="chartRef" :option="chartOption" autoresize />
  </div>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import VChart from 'vue-echarts'
import * as echarts from 'echarts'
import genreMapping from '@/assets/genreMapping.js'

/* ---------- 1. 取数 ---------- */
const raw = ref([])
const genreOptions = computed(() =>
    Object.entries(genreMapping).map(([en, cn]) => ({ label: cn, value: en }))
)
const selectedOption = ref(genreOptions.value[0]?.value || '')

watch(selectedOption, async genre => {
  if (!genre) return
  try {
    const res = await fetch(`/api/queryTop10MoviesInGenre?genre=${encodeURIComponent(genre)}`)
    if (!res.ok) throw new Error(res.status)
    const data = await res.json()
    raw.value = data.map(item => ({
      name: item.title,
      hot: item.popularity,
      box: item.revenue
    }))
  } catch (e) {
    console.error('拉取分类电影数据失败', e)
    raw.value = []
  }
}, { immediate: true })

/* ---------- 2. 排序 ---------- */
const sortKey = ref('')
const sortOrder = ref({ hot: 'desc', box: 'desc' })
const toggle = key => {
  sortOrder.value[key] = sortOrder.value[key] === 'asc' ? 'desc' : 'asc'
}
const setSort = key => {
  sortKey.value = key
  toggle(key)
}
const sorted = computed(() => {
  if (!sortKey.value) return raw.value
  const key = sortKey.value
  const order = sortOrder.value[key]
  return [...raw.value].sort((a, b) => (order === 'asc' ? a[key] - b[key] : b[key] - a[key]))
})

/* ---------- 3. 动态映射 ---------- */
const voteMax = 10               // 窗口半宽
const boxMax  = 3e9              // 票房上限（固定）
let   hotMax  = 2700             // 热度上限（先给默认值，后面算）

const mapHot = v => -(v / hotMax) * voteMax
const mapBox = v => (v / boxMax) * voteMax
const invHot = internal => -(internal / voteMax) * hotMax
const invBox = internal => (internal / voteMax) * boxMax

/* ---------- 4. 图表配置 ---------- */
const chartOption = ref({})

watch(sorted, newVal => {
  /* 动态计算热度映射上限：按 100 向上取整 */
  if (newVal.length) {
    const maxHot = Math.max(...newVal.map(i => i.hot))
    hotMax = Math.ceil(maxHot / 200) * 200 || 200
  }

  const yData = []
  const hotData = []
  const boxData = []

  newVal.forEach(item => {
    yData.push(item.name)
    hotData.push(mapHot(item.hot))
    boxData.push(mapBox(item.box))
  })

  yData.reverse()
  hotData.reverse()
  boxData.reverse()

  chartOption.value = {
    title: { text: '类型电影 · 热度 vs 票房', left: 'center', top: '8%' },
    tooltip: {
      trigger: 'axis',
      axisPointer: { type: 'shadow' },
      formatter: params => {
        const idx = params[0].dataIndex
        const rawItem = sorted.value[sorted.value.length - 1 - idx]
        return [
          `片名：${rawItem.name}`,
          `热度：${rawItem.hot}`,
          `票房：${rawItem.box}`
        ].join('<br/>')
      }
    },
    grid: { top: '20%', bottom: 30, left: '10%', right: '10%' },
    xAxis: {
      type: 'value',
      position: 'top',
      min: -voteMax,
      max: voteMax,
      axisLabel: {
        formatter: val => {
          if (val <= 0) return invHot(val).toFixed(0)
          return (invBox(val) / 1e8).toFixed(1) + '亿'
        }
      },
      splitLine: { lineStyle: { type: 'dashed' } }
    },
    yAxis: {
      type: 'category',
      axisLine: { show: false },
      axisTick: { show: false },
      data: yData
    },
    series: [
      {
        name: '热度',
        type: 'bar',
        data: hotData,
        label: { show: true, position: 'left', formatter: p => invHot(p.value).toFixed(1) },
        itemStyle: {                                          // 【美】薄荷青渐变 + 圆角
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            {offset:0, color: '#fd5c5c'},
            {offset:1, color: '#ffbac0'}
          ]),
          borderRadius: [6, 0, 0, 6]
        },
        // barWidth: '30%',
        barGap: '0%'
      },
      {
        name: '票房',
        type: 'bar',
        data: boxData,
        label: { show: true, position: 'right', formatter: p => (invBox(p.value) / 1e8).toFixed(3) + '亿' },
        itemStyle: {                                          // 【美】暖黄渐变 + 圆角
          color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
            { offset: 0, color: '#ffdc82' },
            { offset: 1, color: '#ffb940' }
          ]),
          borderRadius: [0, 6, 6, 0]
        },
        // barWidth: '30%',
        barGap: '-100%'
      }
    ]
  }
}, { immediate: true })
</script>


<style scoped>
/* 与原样式完全一致 */
.chart-container {
  width: 80vw;
  height: 80vh;
  margin-top: -20vh;
}

.toolbar {
  position: relative;
  top: 5vh;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 8px;
  font-size: 14px;
  /* 保证按钮在最上层，不会被图表遮挡 */
  z-index: 9999;
}

/* 排序按钮组中的按钮样式 */
.sort-group button {
  /* 左边距为6像素 */
  margin-left: 6px;
  /* 内边距，上下4像素，左右10像素 */
  padding: 4px 10px;
  /* 边框，1像素实线，颜色为#ccc */
  border: 1px solid #ccc;
  /* 形状：药丸形 */
  border-radius: 20px;
  /* 背景颜色为白色 */
  background: #fff;
  /* 鼠标指针样式为手型 */
  cursor: pointer;
}

/* 排序按钮组中激活状态的按钮样式 */
.sort-group button.active {
  /* 背景颜色为#409eff */
  background: #409eff;
  /* 文字颜色为白色 */
  color: #fff;
  /* 边框颜色为#409eff */
  border-color: #409eff;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .chart-container {
    height: 300px;
  }
}
</style>